console.log("webrtcPhone say hello ");
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
      typeof define === 'function' && define.amd ? define( ["jquery"], factory):
          (global.webrtcPhone = factory());
}(this, function () {
  console.log('opppppppppwebrtcphone----', JsSIP)
  var serverUrl,
      wssUrl,
      udpUrl,
      stunServers,
      name,
      exten,
      password,
      txtPrivateIdentity,
      txtPublicIdentity,
      autoAnswer,
      oConfigCall,
      oConfigSendMessage,
      sipStack,
      callSession,
      oSipSessionTransferCall,
      registerSession;
  var self;
  function webrtcPhone() {

    self = this;
    console.log('jssip---init之前---', SipHelper, this.jsSipPhone)
    this.init = function(data) {
      console.log('webphone-init--1--', data)
        serverUrl = data.serverUrl;
        name = data.name;
        exten = data.exten;
        password = data.password;
        txtPrivateIdentity = exten;
        txtPublicIdentity = 'sip:' + exten + '@' + serverUrl;
      if (!this.jsSipPhone) {  // 是否初始化
        serverUrl = data.serverUrl;
        name = data.name;
        exten = data.exten;
        password = data.password;
        wssUrl = data.wssUrl;
        udpUrl = data.udpUrl;
        stunServers = data.stunServers;
        autoAnswer = data.autoAnswer;
        txtPrivateIdentity = exten;
        txtPublicIdentity = 'sip:' + exten + '@' + serverUrl;
        wssUrl = 'wss://' + wssUrl;
        udpUrl = 'udp://' + udpUrl;
        stunServers = [{ urls: 'stun:'+stunServers+''}];
        // stunServers = [{ urls: 'stun:'+stunServers+''},{ urls: 'turn:'+stunServers+''}];
        console.log('=======', 'stun:'+stunServers+'')
        // SIPml.init(engineErrorCb);  // 删除sipml初始化
        this.jsSipPhone = SipHelper.getInstance();
        console.log('实例化jssip---', this.jsSipPhone.instance)
        let jsSipParam = {
          data: data,
          wssUrl: wssUrl,
          udpUrl: udpUrl,
          txtPublicIdentity: txtPublicIdentity,
          txtPrivateIdentity: txtPrivateIdentity,
          stunServers:stunServers
        }
        this.jsSipPhone.init(jsSipParam);
        console.log('实例化修改---666777', jsSipParam, this.jsSipPhone, this.jsSipPhone.session);
        oConfigSendMessage = {
          events_listener: {events: '*', listener: onSipEventSession}
        };
        var audioRemote = document.getElementById("audio_remote");
        oConfigCall = {
          video_local: null,
          video_remote: null,
          audio_remote: audioRemote,
          screencast_window_id: 0x00000000, // entire desktop
          bandwidth: { audio: undefined, video: undefined },
          video_size: { minWidth: undefined, minHeight: undefined, maxWidth: undefined, maxHeight: undefined },
          events_listener: {events: '*', listener: onSipEventSession},
          sip_caps: [
            {name: '+g.oma.sip-im'},
            {name: 'language', value: '\"en,fr\"'}
          ]
        };

      }
    }

    this.login = function() {
      // jsSip
      console.log('登录jssip-----login')
      this.jsSipPhone.login();
    }

    this.logout = function() {
      this.jsSipPhone.logout();
      sipStack = null;
      callSession = null;
      registerSession = null;
      console.log('jssip的登出--', this.jsSipPhone)
    }


    this.call = function(phoneNumber) {
      console.log('webrtc-phone---外呼', 'sip:' + phoneNumber + '@' + serverUrl)
      console.log('---外呼--', this.jsSipPhone.session)
      if (!this.jsSipPhone.session) {
        this.jsSipPhone.call('sip:' + phoneNumber + '@' + serverUrl);
      }
    }


    this.answer = function(e) {
      console.log('--------answer--', new Date(), this.jsSipPhone.session)
      if (this.jsSipPhone.session) {
        this.jsSipPhone.answer(oConfigCall);
      }
    }


    this.hangup = function(e) {
      this.jsSipPhone.hangUp();
    }

    /**
     * 开始静音 结束静音
     * @param bMute true false
     */
    // Mute OR Unmute the call
    this.sipToggleMute = function(bMute) {
      console.log('是否---静音-======', bMute)
      if (this.jsSipPhone.session) {
        if(bMute == true) {
          let options = {audio: true};
          this.jsSipPhone.session.mute(options);
        } else {
          let options = {audio: false};
          this.jsSipPhone.session.unmute(options);
        }
        callSession.bMute = bMute;
      }
    }

    this.stopStack = function(e) {
      if (sipStack) {
        sipStack.stop();
        sipStack = null;
        callSession = null;
      }
    }

    this.onEvent = function (event) {
    }

    this.sipSendDTMF = function(c) {
      console.log('webrtc-----phone---', c, callSession, this.jsSipPhone.session)
      if (this.jsSipPhone.session && c) {
        this.jsSipPhone.sendDTMF(c);
      }
    }

  }


  // Callback function for SIP sessions (INVITE, REGISTER, MESSAGE...)
  /* SIPml.Session.Event */
  function onSipEventSession(e) {
    console.log('==session event = ' + e.type);
    self.onEvent(e)
  }
  
  // 向后台发送错误日志
  function sendWebPhoneErrorLog(data, extract, statusTxt, callBack) {
    console.log('发送错误webrtc日志--', callBack);
    let param = {};
    param.accountId = data.name; // 坐席id
    param.entId = data.entId; // 企业id
    param.sipNumber = data.exten; // 分机号
    param.sipType = '5'; // 分机类型webrtc默认5
    param.status = statusTxt ? statusTxt : 'disconnected'; // 分机注销断开的状态
    param.ip = ''; // 本地ip
    param.extract = extract; // 附加参数
    console.log('打印参数--===jssip==errorLog参数', param);
    $.ajax({
        url: '/logmanage/info/webRtcMsg',
        timeout: '5000', // 5s超时
        type: "POST",
        data: JSON.stringify(param),
        contentType: 'application/json;',
        dataType: 'json',
        success: function(res) {
            if(callBack) {
                callBack(res);
            }
        }
    })
  }

  // jssip
  class SipHelper {
    static instance;
    coolPhone;
    session;
    loginParam;
    /**
     * 单例
     */
    static getInstance() {
        if (!SipHelper.instance) {
            SipHelper.instance = new SipHelper();
        };
        return SipHelper.instance;
    }

    /**
     * 电话断掉后，需要初始化的数据或者执行的方法
     */
    init(param){
        this.session = null; // 会话id清空
        this.loginParam = param ? param : (this.loginParam ? this.loginParam : {});
        console.log('初始化-jasip-', this.session, this.loginParam) // 全局状态 挂起初始化
    }

    /**
     * 分机注册，登录
     * @param {*} phoneNumber 分机号码
     */
    login() {
        console.log('登录时的--jssip======', this.loginParam)
        //创建一个 JsSIP User Agent
        // 登录
        const configuration = {
          sockets: [new JsSIP.WebSocketInterface(this.loginParam.wssUrl)],
          uri: this.loginParam.txtPublicIdentity,
          password: this.loginParam.data.password,
          session_timers: false, // 启用会话计时器（根据RFC 4028)
          user_agent: 'HYTX_WebRTC_phone',
          // outbound_proxy_set: wsUri,
          // display_name: String(phone),
          // autostart: true,   // 自动连接
          register: true, // 自动就绪-自动注册
        };
        JsSIP.debug.enable('JsSIP:*');
        this.coolPhone = new JsSIP.UA(configuration);

        // Starting the User Agent
        this.setUAEvent();
        this.coolPhone.start();
    }

    /**
     * 对外暴漏事件
     * @param {*} msg，连接状态/分机注册状态/call状态
     */
    setOutEvent(msg) {
      self.onEvent(msg);
    }

    /**
   * 绑定ua事件
   * @param {*} ua 
   */
    setUAEvent(ua) {
        console.log('jssip中setUAEvent---', self)
        // ws 开始尝试连接
        this.coolPhone.on('connecting',  (args)=> {
            console.log('jssip-ws尝试连接');
            let msg = {
              type: 'connecting',
              description: 'connecting'
            }
            this.setOutEvent(msg);
        });

        // ws 连接完毕
        this.coolPhone.on('connected', ()=> {
          console.log('jssip-ws连接完毕', self);
          let msg = {
            type: 'connected',
            description: 'connected'
          }
          this.setOutEvent(msg);
        });

        // ws 连接失败
        this.coolPhone.on('disconnected', (e)=> {
          console.log('jssip-ws连接失败', e);
          let msg = {
            type: 'disconnected',
            description: 'disconnected'
          }
          this.setOutEvent(msg);
          // 发送错误日志
          if (window && window.webrtcPhoneIsLogin && this.loginParam && this.loginParam.data) {
            // 调用故障errlog接口
            let extendinfo = 'code: ' + e.code + '||reason: ' + e.reason+ '||error: ' + e.error;
            let statusTxt = 'disconnected';
            sendWebPhoneErrorLog(this.loginParam.data, extendinfo, statusTxt, function() {
              console.log('发送错误webrtc日志-成功')
            })
          }
        })

        // SIP 注册成功
        this.coolPhone.on('registered', e => {
            console.log('jssip-SIP已注册', e);
            let msg = {
              type: 'registered',
              description: 'registered'
            }
            this.setOutEvent(msg);
        });

        //  SIP 注册失败
        this.coolPhone.on('registrationFailed', e => {
            console.log('jssip-SIP注册失败', e);
            let msg = {
              type: 'registrationFailed',
              description: 'registrationFailed'
            }
            // 发送错误日志
            if (window && window.webrtcPhoneIsLogin && this.loginParam && this.loginParam.data) {
              // 调用故障errlog接口
              let extendinfo = 'response: ' + e.response + '||cause: ' + e.cause;
              let statusTxt = 'registrationFailed';
              sendWebPhoneErrorLog(this.loginParam.data, extendinfo, statusTxt, function() {
                console.log('发送错误webrtc日志-成功')
              })
            }
            this.setOutEvent(msg);
        });

        // SIP 取消注册
        this.coolPhone.on('unregistered', e => {
            console.log('jssip-SIP主动取消注册或注册后定期重新注册失败', e);
            console.log('===========jssip--取消注册unregistered-----', window.webrtcPhoneIsLogin, this.loginParam);
            let msg = {
              type: 'unregistered',
              description: 'unregistered'
            }
            // 发送错误日志
            if (window && window.webrtcPhoneIsLogin && this.loginParam && this.loginParam.data) {
              // 调用故障errlog接口
              let extendinfo = 'response: ' + e.response + '||cause: ' + e.cause;
              let statusTxt = 'unregistered';
              sendWebPhoneErrorLog(this.loginParam.data, extendinfo, statusTxt, function() {
                console.log('发送错误webrtc日志-成功')
              })
            }
            this.setOutEvent(msg);
        });

        // IM消息 事件
        this.coolPhone.on('newMessage', e => console.log('jssip-im新消息事件'));

        // 来电或者外呼事件
        this.coolPhone.on('newRTCSession', e => {
           console.log(`新的${e.originator === 'local' ? '外呼' : '来电'}`, e.originator, e);
            const session = e.session;
            this.session = session;
            const peerconnection = session.connection;
            if (e.originator === 'local') {
                peerconnection.addEventListener('addstream', (event) => {
                    const audio = document.querySelector('.audio');
                    console.log('onaddstream from remote - ----locallocallocal-----', audio)
                    audio.srcObject = event.stream;
                });
            } else {
                const callers = session.remote_identity.uri.user;
            }

            // 接听失败
            session.on('failed', mdata => {
                this.init();  // ??
                console.log('来电的时候 拒接或者 还没接听对方自己就挂断了', mdata);
                // 发送错误日志
                if (window && window.webrtcPhoneIsLogin && this.loginParam && this.loginParam.data) {
                  // 调用故障errlog接口
                  let extendinfo = 'msg: ' + '接听失败' + '||cause: ' + mdata.cause + '||data: ' + (mdata.message && mdata.message.data) || '' + '||body: ' + (mdata.message && mdata.message.body) || ''+ '||originator: ' + (mdata.originator);
                  let statusTxt = 'failed';
                  sendWebPhoneErrorLog(this.loginParam.data, extendinfo, statusTxt, function() {
                    console.log('发送错误webrtc日志-成功')
                  })
                }
            });

            // 接听成功
            session.on("accepted", (response, cause) => {
                console.log('接听成功**', response, cause, new Date(), new Date().getSeconds())
            });

            // 接听成功后 挂断
            session.on('ended', (e) => {
                console.log('接听结束', e);
                this.init(); // ??
            });

            // 接听流
            session.on('peerconnection', (data) => {
              console.log('pppppppppppp监听liuliu----', data)
              data.peerconnection.onaddstream = function (ev) {
                var audioRemote = document.getElementById("audio_remote");
                console.info('onaddstream from remote - ***', ev, new Date(), new Date().getSeconds(), audioRemote);
                audioRemote.srcObject = ev.stream;
                audioRemote.play();
              }
            });

            // 通话被挂起
            session.on('hold', (data) =>{
                const org = data.originator;
                if(org === 'local'){
                    console.log('通话被本地挂起:', org);
                }else{
                    console.log('通话被远程挂起:', org);
                }
            });

            // 通话被继续
            session.on('unhold', (data) =>{
                const org = data.originator;
                if(org === 'local'){
                    console.log('通话被本地继续:', org)
                }else{
                    console.log('通话被远程继续:', org);
                }
            });
  
            // 监听icecandidate
            let iceCandidateCount = 0;
            session.on('icecandidate', (data) => {
              console.log('jssip======session中监听icecandidate', data);
              console.log('iceCandidateCount: ', iceCandidateCount);
	            iceCandidateCount = iceCandidateCount + 1;
              if(iceCandidateCount > 3) {
                data.ready();
              }
            });
        });
    }

    /**
     * 登出
     */
    logout() {
        this.loginParam = {};
        if(this.coolPhone) {
          this.coolPhone.unregister(); // 注销
          this.coolPhone.stop({ register: true });
        }
    }

    /**
     * 拨打
     * @param {*} phoneNumber 拨打号码
     */
    call(phoneNumber) {
        const options = {
            eventHandlers: {
                progress(e) {
                    console.log('正在呼叫:', e);
                },
                failed(e) {
                    console.log('呼叫失败: ', e);
                },
                ended(e) {
                    console.log('呼叫结束:' + e.originator === 'remote' ? '对方挂断' : '自己挂断', e);
                },
                confirmed(e) {
                    console.log('呼叫接受' + e.originator === 'remote' ? '自己已接受' : '对方已接受', e);
                }
            },
            mediaConstraints: { 'audio': true, 'video': false }
        };
        // this.coolPhone.call(`sip:${phoneNumber}`, options);
        this.coolPhone.call(`${phoneNumber}`, options);
    }


    /**
    * 接听
    */
    answer(oConfigCall) {
        console.log('===========jssip接听接听-----', window.webrtcPhoneIsLogin, this.loginParam);
        console.log('调用接听接口------', new Date().getSeconds(), this.loginParam.stunServers)
        let stun = this.loginParam.stunServers;
        let options = {
                eventHandlers: {
                  progress(e) {
                      console.log('正在接听:', e);
                  },
                  failed(e) {
                      console.log('接听失败: ', e);
                  },
                  ended(e) {
                      console.log('接听结束:', e);
                  },
                  confirmed(e) {
                      console.log('接听动作完成', e);
                  }
                },
                mediaConstraints: { 'audio': true, 'video': false },
                mediaStream: null,
                // pcConfig: { 'iceServers': stun },
                pcConfig: { 
                  'iceServers': stun,
                  // 'iceTransportPolicy': 'relay'
                  'iceTransportPolicy': 'all',
                  'rtcpMuxPolicy': 'negotiate',
                  'iceCandidatePoolSize': 1
                },
                render: {
                  remote: oConfigCall.audio_remote,
                }
        }
        console.log('===========接听-----', options);
        this.session.answer(options);
    }

    /**
     * 挂断
     */
    hangUp() {
        if (this.session && this.session.isEnded() === false) {
            this.session.terminate();
        }
        this.session = null;
    }

    /**
     * 挂起
     */
    hold(){
        this.session.hold({ useUpdate: false });
    }

    /**
     * 继续
     */
    unhold(){
        this.session.unhold({ useUpdate: false });
    }

    /***
     * sendDTMF
     */
     sendDTMF(c) {
      console.log('===========DTMF', c)
      this.session.sendDTMF(c);
     }

  }

  return webrtcPhone;

}))